from django.http import Http404

from rest_framework import serializers
from rest_framework import mixins, status

from rest_framework.response import Response
from rest_framework.views import APIView
from rest_framework.viewsets import ModelViewSet, GenericViewSet
from plumes.models import Channel, Article, Comment
from plumes.serializers import ChannelSerializer, ChannelListSerializer, ArticleInfoSerializer, \
    PublishArticleSerializer, PublishCommentSerializer, ArticleSearchSerializer


class ChannelsViewSet(mixins.ListModelMixin, GenericViewSet):
    """获取首页左侧栏中的频道列表"""
    # channels/
    queryset = Channel.objects.all()
    serializer_class = ChannelSerializer
    lookup_value_regex = '\d+'
    # pagination_class = None

# /article/{id}/channel/?page=<页码>


class ChannelListViewSet(ModelViewSet):
    """
    1.获取文章列表
    """
    queryset = Article.objects.all()
    serializer_class = ChannelListSerializer
    lookup_value_regex = '\d+'

    def get_queryset(self):
        id = self.kwargs['id']
        if id:
            if id == '-1':
                article = Article.objects.order_by('-visits')
                return article
            article = Article.objects.filter(channel_id=id)

        return article


class ArticleInfoViewSet(ModelViewSet):
    """文章详情"""
    queryset = Article.objects.all()
    serializer_class = ArticleInfoSerializer
    lookup_value_regex = '\d+'
    # 关闭分页
    pagination_class = None


class CollectSView(APIView):
    """收藏"""
    def put(self, request, pk):
        user = request.user
        try:
            article = Article.objects.get(id=pk)
        except Exception as e:
            return Http404
        if user in article.collected_users.all():
            article.collected_users.remove(user.id)
            return Response({
                'success': True,
                "message": "取消收藏成功"
            })
        try:
            article.collected_users.add(user.id)
        except Exception as e:
            print(e)
        return Response({
            'success': True,
            "message": "收藏成功"
        })


class PublishArticleView(mixins.CreateModelMixin,
                         GenericViewSet):
    """发布文章序"""
    queryset = Article.objects.all()
    serializer_class = PublishArticleSerializer
    lookup_value_regex = '\d+'
    # 关闭分页
    pagination_class = None

    def create(self, request, *args, **kwargs):
        serializer = self.get_serializer(data=request.data)
        serializer.is_valid(raise_exception=True)
        article = serializer.save()
        return Response({
            'articleid': article.id,
            'message': 'OK',
            'success': True,
        }, status=status.HTTP_201_CREATED)


class PublishCommentView(mixins.CreateModelMixin,
                         GenericViewSet):
    """评论文章"""
    queryset = Comment.objects.all()
    serializer_class = PublishCommentSerializer
    lookup_value_regex = '\d+'
    # 关闭分页
    pagination_class = None

    def create(self, request, *args, **kwargs):
        serializer = self.get_serializer(data=request.data)
        serializer.is_valid(raise_exception=True)
        serializer.save()
        return Response({
            'message': 'OK',
            'success': True,
        }, status=status.HTTP_201_CREATED)


# GET /search/?q=<关键字>&page=<页码>&page_size=<页容量>
class ArticleSearchView(mixins.ListModelMixin, GenericViewSet):
    queryset = Article.objects.all()
    serializer_class = ArticleSearchSerializer
    lookup_value_regex = '\d+'

    def get_queryset(self):
        # ① 获取参数并进行校验
        keyword = self.request.GET.get('text')
        if not keyword:
            raise serializers.ValidationError({'code': 400,
                                               'message': '缺少搜索关键字!'})

        # ② 使用 haystack 检索数据
        from haystack.query import SearchQuerySet
        query = SearchQuerySet()
        search_res = query.auto_query(keyword).load_all()

        request_li = []
        for res in search_res:
            info = res.object
            request_li.append(info)

        return request_li
